package com.eds.pojo;


import com.eds.exception.BusException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * 统一返回结果类
 *
 * @param <T> 返回数据的类型
 * @author eds
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseResult<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    private Integer code;

    /**
     * 提示消息
     */
    private String message;

    /**
     * 返回数据
     */
    private T data;
    /**
     * 提示消息
     */
    private String role;

    /**
     * 构建成功结果
     *
     * @return BaseResult
     */
    public static <T> BaseResult<T> ok() {
        return new BaseResult<T>(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage(), null, null);
    }

    /**
     * 构建带有数据的成功结果
     *
     * @param data 返回数据
     * @return BaseResult
     */
    public static <T> BaseResult<T> ok(T data) {
        return new BaseResult<>(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage(), data, null);
    }

    /**
     * 构建带有消息的成功结果
     *
     * @param message 提示消息
     * @return BaseResult
     */
    public static <T> BaseResult<T> ok(String message) {
        return new BaseResult<>(CodeEnum.SUCCESS.getCode(), message, null, null);
    }

    /**
     * 构建带有消息和数据的成功结果
     *
     * @param message 提示消息
     * @param data    返回数据
     * @return BaseResult
     */
    public static <T> BaseResult<T> ok(String message, T data) {
        return new BaseResult<>(CodeEnum.SUCCESS.getCode(), message, data, null);
    }

    /**
     * 构建带有消息，角色和数据的成功结果
     *
     * @param message 提示消息
     * @param data    返回数据
     * @return BaseResult
     */
    public static <T> BaseResult<T> ok(String message, T data, String role) {
        return new BaseResult<>(CodeEnum.SUCCESS.getCode(), message, data, role);
    }

    /**
     * 构建失败结果
     *
     * @return BaseResult
     */
    public static <T> BaseResult<T> error() {
        return new BaseResult<>(CodeEnum.SYSTEM_ERROR.getCode(), CodeEnum.SYSTEM_ERROR.getMessage(), null, null);
    }

    /**
     * 根据指定的状态码和消息构建失败结果
     *
     * @param codeEnum 状态码枚举
     * @return BaseResult
     */
    public static <T> BaseResult<T> error(CodeEnum codeEnum) {
        return new BaseResult<>(codeEnum.getCode(), codeEnum.getMessage(), null, null);
    }

    /**
     * 根据指定的状态码、消息和数据构建结果
     *
     * @param codeEnum 状态码枚举
     * @param data     返回数据
     * @return BaseResult
     */
    public static <T> BaseResult<T> error(CodeEnum codeEnum, T data) {
        return new BaseResult<>(codeEnum.getCode(), codeEnum.getMessage(), data, null);
    }

    /**
     * 根据业务异常构建失败结果
     *
     * @param e 业务异常
     * @return BaseResult
     */
    public static <T> BaseResult<T> error(BusException e) {
        return (BaseResult<T>) new BaseResult<>(e.getCode(), e.getMessage(), e.getData(), null);
    }

    /**
     * 根据异常构建失败结果
     *
     * @param e 异常
     * @return BaseResult
     */
    public static <T> BaseResult<T> error(Exception e) {
        return new BaseResult<>(
                CodeEnum.SYSTEM_ERROR.getCode(),
                e.getMessage(),
                null,
                null
        );
    }

    /**
     * 判断是否成功
     *
     * @return 是否成功
     */
    public boolean isSuccess() {
        return CodeEnum.SUCCESS.getCode().equals(this.code);
    }

    /**
     * 判断是否失败
     *
     * @return 是否失败
     */
    public boolean isError() {
        return !isSuccess();
    }


    /**
     * 获取数据，如果数据为空则抛出异常
     *
     * @param message 错误消息
     * @return 数据
     * @throws BusException 业务异常
     */
    public T getDataOrThrow(String message) {
        if (this.data == null) {
            throw BusException.error(CodeEnum.DATA_NOT_FOUND.getCode(), message);
        }
        return this.data;
    }
}